﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace LambdaExpression
{
    delegate int GetMaxValueDelegate(int[] valuesArray);
    delegate string GetString(int a, string b);
    class Program
    {
        static void Main(string[] args)
        {

            /*
             * Lambda 表达式：参考：http://msdn.microsoft.com/zh-cn/library/bb397687.aspx
             * 
             * Lambda 表达式实际上是一个匿名方法
             * Lambda 表达式的形式：(输入参数列表) => (表达式)
             * 
             * 参数列表中的参数类型 与 表达式返回值的类型 实际上是由委托类型决定的。 例如：
             * 
             * 定义一个委托：delegate int GetMaxValueDelegate(int[] valuesArray); 
             * 将委托指向一个方法地址(匿名方法)：GetMaxValueDelegate GetMaxValue = n => { return n[0]; };
             * n是一个整形数组，return n[0]返回一个整形
             * 
             * 上面的示例中，请注意委托签名具有一个 int数组类型的输入参数，并返回 int。可以将 Lambda 表达式
             * 转换为该类型的委托，因为该表达式也具有一个输入参数 (x)，以及一个编译器可隐式转换为 int 类型的返回值。
             * 
             * 适用于匿名方法的所有限制也适用于 Lambda 表达式。有关更多信息，请参见匿名方法（C# 编程指南）：
             * http://msdn.microsoft.com/zh-cn/library/0yw3tz5k.aspx
             * 
             * 实际上，Lambda 表达式本身没有类型，因为常规类型系统没有“Lambda 表达式”这一内部概念。 
             * 但是，有时会不正式地论及 Lambda 表达式的“类型”。在这些情况下，类型是指委托类型或 Lambda 
             * 表达式所转换为的 Expression 类型。
             * 
             * 使用细节：
             * 1. 在 is 或 as 运算符的左侧不允许使用 Lambda。
             * 2. => 运算符具有与赋值运算符 (=) 相同的优先级，并且是右结合运算符。
             * 3. 没有参数时用空括号表示不可省略： DelegateMethod = ( ) => x * 2
             * 4. 只有一个参数可以省略括号：DelegateMethod = x => x * 2
             * 5. 多个参数用逗号分隔 DelegateMethod = (x, y) => x * y
             * 6. Lambda 包含的参数数量必须与委托类型包含的参数数量相同。
             * 7. Lambda 中的每个输入参数必须都能够隐式转换为其对应的委托参数。
             * 8. Lambda 的返回值（如果有）必须能够隐式转换为委托的返回类型。
             * 9. 参数列表 要么全部是隐式参数类型，要么全部为显式参数类型。不可一个隐式一个显式。
             * 
             * 下列规则适用于 Lambda 表达式中的变量范围：
             *  捕获的变量将不会被作为垃圾回收，直至引用变量的委托超出范围为止。
             *  在外部方法中看不到 Lambda 表达式内引入的变量。
             *  Lambda 表达式无法从封闭方法中直接捕获 ref 或 out 参数。
             *  Lambda 表达式中的返回语句不会导致封闭方法返回。
             *  Lambda 表达式不能包含其目标位于所包含匿名函数主体外部或内部的 goto 语句、break 语句或 continue 语句。
             */








            GetMaxValueDelegate GetMaxValue = n => { return n[0]; };
            GetString GetStringValue = (a, b) => a.ToString() + b;
            Console.WriteLine(GetMaxValue(new int[] {1, 2, 3, 4, 5}));
            Console.WriteLine(GetStringValue(1, "abc"));
            Console.Read();

            int[] array = { 1, 2, 0 };
            Console.WriteLine(array.Any(x => x == 0));
            Console.Read();
        }
    }
}
